<template>
	<Upload v-bind="bindValue" v-model:fileList="fileListRef" :before-upload="beforeUpload" @change="handleChange">
		<a-button>
			<UploadOutlined />
			{{ $props.title }}
		</a-button>
	</Upload>
</template>
<script lang="ts">
import { Upload } from 'ant-design-vue';
import { UploadOutlined } from '@ant-design/icons-vue';
import { computed, defineComponent, ref, watch } from 'vue';
import type { UploadChangeParam } from 'ant-design-vue';
import { useMessage } from '@/hooks/web/useMessage';
import { omit } from 'lodash-es';
import { simpleUploadProps } from '../props';
import { isFunction } from '@/utils/is';

export default defineComponent({
	name: 'SimpleUpload',
	components: {
		Upload,
		UploadOutlined,
	},
	props: simpleUploadProps,
	emits: ['change', 'update:value'],
	setup(props, { attrs, emit }) {
		const fileListRef = ref([]);
		let responseList = ref<Recordable[]>([]);

		const { createMessage } = useMessage();

		const bindValue = computed((): Recordable => {
			let multiple = true;
			if (props.maxNumber == 1) {
				multiple = false;
			}
			const value = { ...attrs, ...props, multiple };
			return omit(value, 'onChange');
		});

		watch(
			() => props.value,
			value => {
				!value.length && (fileListRef.value = []);
			},
			{ immediate: true },
		);

		function beforeUpload(file: File) {
			const { maxSize } = props;
			// 设置最大值，则判断
			if (maxSize && file.size / 1024 / 1024 >= maxSize) {
				createMessage.error(`只能上传不超过${maxSize}MB的文件`);
			}
			return false;
		}

		async function handleChange({ file, fileList }: UploadChangeParam) {
			const { api, maxSize, maxNumber, uploadParams } = props;
			if (!api || !isFunction(api)) {
				return console.warn('upload api must exist and be a function');
			}

			if (maxSize && file.size! / 1024 / 1024 >= maxSize) {
				const index = fileList.findIndex(item => item.uid === file.uid);
				index !== -1 && fileList.splice(index, 1);
				return;
			}

			if (file.status === 'removed') {
				handleRemove(file);
				return;
			}

			if (maxNumber > 1 || maxNumber !== Infinity) {
				let resFileList = fileList;
				resFileList = resFileList.slice(-maxNumber);
				const index = resFileList.findIndex(item => item.uid === file.uid);
				fileListRef.value = resFileList as any;

				if (index === -1) {
					return;
				}
			}

			try {
				const data = await api?.({
					data: {
						...(uploadParams || {}),
					},
					file: file,
				});

				responseList.value.push({ file, responseData: data });
				
				const rs = responseList.value.map(i => i.responseData);
				emit('update:value', rs);
				emit('change', rs);

				return {
					success: true,
					error: null,
				};
			} catch (e) {
				return {
					success: false,
					error: e,
				};
			}
		}

		function handleRemove(file: any) {
			const index = responseList.value.findIndex(item => item.file.uid === file.uid);
			index !== -1 && responseList.value.splice(index, 1);

			const rs = responseList.value.map(i => i.responseData);
			emit('update:value', rs);
			emit('change', rs);
		}

		return {
			bindValue,
			fileListRef,
			beforeUpload,
			handleChange,
		};
	},
});
</script>
<style lang="less" scoped>
:deep(.ant-upload-list) {
	max-height: 150px;
	overflow: auto;
}
</style>
